#ifndef __OPENGLSHADER_PROGRAM_H__
#define __OPENGLSHADER_PROGRAM_H__

#include "GL/glew.h"
#include "Graphics/OpenGL/OpenGLTexture.h"
#include "Graphics/ShaderProgram.h"

namespace RayFrame
{
  class DLL_DECLARE OpenGLShaderProgram: public ShaderProgram
  {
  protected:
    typedef std::map<STRING, GLhandleARB> ShaderVarMap;
    typedef ShaderVarMap::iterator ShaderVarMapIter;
    typedef std::map<int, OpenGLTexture*> ShaderTextureMap;
    typedef ShaderTextureMap::iterator ShaderTextureMapIter;

    ShaderTextureMap m_textures;
    ShaderVarMap m_handles;

    GLuint  m_ID;
  protected:
    virtual void internalCreate();
    virtual void internalDestroy();

    virtual void Begin();
    virtual void End();
    virtual bool BindImage(STRING varName, Texture* image, Shader::ShaderType type = Shader::VERTEX_SHADER);
  public:
    ~OpenGLShaderProgram(){ internalDestroy(); };

    virtual Shader* CreateVertexShader();
    virtual Shader* CreatePixelShader();

    inline GLhandleARB GetHandle(STRING name);

    virtual void SetShaderParam(STRING name, const int val, Shader::ShaderType type);
    virtual void SetShaderParam(STRING name, const float val, Shader::ShaderType type);
    virtual void SetShaderParam(STRING name, glm::vec2 val, Shader::ShaderType type);
    virtual void SetShaderParam(STRING name, glm::vec3 val, Shader::ShaderType type);
    virtual void SetShaderParam(STRING name, glm::vec4 val, Shader::ShaderType type);
    virtual void SetShaderParam(STRING name, glm::mat4 val, Shader::ShaderType type);
  };

  const int INVALIE_SHADER_HANDLE = -1;
}

#endif
